home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / fsstat / print.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-16  |  17.3 KB  |  517 lines

  1. /*
  2.  * print.c --
  3.  *    Routines to print out program execution times, and filesystem stats.
  4.  */
  5.  
  6. #include "sprite.h"
  7. #include "status.h"
  8. #include "stdio.h"
  9. #include "proc.h"
  10. #include "vm.h"
  11. #include "spriteTime.h"
  12. #include "sysStats.h"
  13. #include "kernel/fs.h"
  14. #include "kernel/fsStat.h"
  15. #include "kernel/sched.h"
  16. #include "kernel/vm.h"
  17.  
  18.  
  19. /*
  20.  *----------------------------------------------------------------------
  21.  *
  22.  * PrintTimes --
  23.  *
  24.  *    Print the resource usage (user and kernel CPU time) and elapsed time.
  25.  *
  26.  * Results:
  27.  *    None.
  28.  *
  29.  * Side effects:
  30.  *    Prints to the specified stream
  31.  *
  32.  *----------------------------------------------------------------------
  33.  */
  34. void
  35. PrintTimes(stream, usagePtr, timePtr)
  36.     FILE *stream;
  37.     Proc_ResUsage *usagePtr;
  38.     Time *timePtr;
  39. {
  40.     Time delta;
  41.     if (usagePtr != NULL) {
  42.     Time_Add(usagePtr->userCpuUsage, usagePtr->childUserCpuUsage,
  43.                      &delta);
  44.     fprintf(stream, "%d.%03du ", delta.seconds,
  45.                    delta.microseconds / 1000);
  46.     Time_Add(usagePtr->kernelCpuUsage, usagePtr->childKernelCpuUsage,
  47.                      &delta);
  48.     fprintf(stream, "%d.%03ds ", delta.seconds,
  49.                    delta.microseconds / 1000);
  50.     }
  51.     if (timePtr != NULL) {
  52.     int seconds = timePtr->seconds;
  53.     if (seconds >= 3600) {
  54.         fprintf(stream, "%d:", seconds / 3600);
  55.         seconds = seconds % 3600;
  56.     }
  57.     if (seconds >= 60) {
  58.         fprintf(stream, "%d:", seconds / 60);
  59.         seconds = seconds % 60;
  60.     }
  61.     fprintf(stream, "%d.%03d", seconds,
  62.                    timePtr->microseconds / 1000);
  63.     }
  64.     fprintf(stream, "\n");
  65. }
  66.  
  67.  
  68. /*
  69.  *----------------------------------------------------------------------
  70.  *
  71.  * PrintIdleTime --
  72.  *
  73.  *    Given two samples sched module statistics, this computes
  74.  *    the differenc in idle ticks and, using the time, computes
  75.  *    a utilization.
  76.  *
  77.  * Results:
  78.  *    None.
  79.  *
  80.  * Side effects:
  81.  *    Prints to the specified stream
  82.  *
  83.  *----------------------------------------------------------------------
  84.  */
  85. void
  86. PrintIdleTime(stream, startSchedPtr, endSchedPtr, timePtr)
  87.     FILE *stream;
  88.     Sched_Instrument *startSchedPtr, *endSchedPtr;
  89.     Time *timePtr;
  90. {
  91.     register         highTicks;
  92.     double         lowTicks;
  93.     Sys_MachineInfo    machineInfo;
  94.     int            numProcessors;
  95.     ReturnStatus    status;
  96.     int            i;
  97.     int            totalIdleTicksPerSecond;
  98.     double        totalLowTicks;
  99.     int            totalCS;
  100.     int            totalInvCS;
  101.     int            totalFullCS;
  102.     int            diffCS;
  103.     int            diffInvCS;
  104.     int            diffFullCS;
  105.  
  106.     Sched_Instrument zeroStats;
  107.     if (startSchedPtr == NULL) {
  108.     bzero(&zeroStats, sizeof(Sched_Instrument));
  109.     startSchedPtr = &zeroStats;
  110.     }
  111.     status = Sys_GetMachineInfo(sizeof(Sys_MachineInfo), &machineInfo);
  112.     if (status != SUCCESS) {
  113.     printf("Sys_GetMachineInfo returned 0x%x.\n", status);
  114.     exit(status);
  115.     }
  116.     numProcessors = machineInfo.processors;
  117.     totalLowTicks = 0;
  118.     totalIdleTicksPerSecond = 0;
  119.     totalCS = 0;
  120.     totalInvCS = 0;
  121.     totalFullCS = 0;
  122.     for (i = 0; i < numProcessors; i++) {
  123.     if (numProcessors != 1) {
  124.         fprintf(stream, "<%2d> ", i);
  125.     }
  126.     highTicks = endSchedPtr->processor[i].idleTicksOverflow -
  127.             startSchedPtr->processor[i].idleTicksOverflow;
  128.     lowTicks = endSchedPtr->processor[i].idleTicksLow -
  129.             startSchedPtr->processor[i].idleTicksLow;
  130.     
  131.     if (highTicks != 0) {
  132.         fprintf(stream, "(High ticks = %d)", highTicks);
  133.     }
  134.     if (timePtr->seconds == 0 && timePtr->microseconds == 0) {
  135.         fprintf(stream, "Idle ticks --/-- = 100%% Idle, ");
  136.     } else {
  137.         lowTicks /= (double)timePtr->seconds + 
  138.         (double) (timePtr->microseconds)/1000000.;
  139.         totalLowTicks += lowTicks;
  140.         totalIdleTicksPerSecond += 
  141.         endSchedPtr->processor[i].idleTicksPerSecond;
  142.         diffCS = endSchedPtr->processor[i].numContextSwitches - 
  143.             startSchedPtr->processor[i].numContextSwitches;
  144.         totalCS += diffCS;
  145.         diffInvCS = endSchedPtr->processor[i].numInvoluntarySwitches - 
  146.         startSchedPtr->processor[i].numInvoluntarySwitches;
  147.         totalInvCS += diffInvCS;
  148.         diffFullCS = endSchedPtr->processor[i].numFullCS - 
  149.         startSchedPtr->processor[i].numFullCS;
  150.         totalFullCS + diffFullCS;
  151.         fprintf(stream, 
  152.         "Idle ticks %0.0f/%d = %6.2f%% Idle, Context Sw. %d inv %d full %d,",           lowTicks,
  153.            endSchedPtr->processor[i].idleTicksPerSecond,
  154.            (double)lowTicks/
  155.            (double)endSchedPtr->processor[i].idleTicksPerSecond * 100.,
  156.            diffCS, diffInvCS, diffFullCS);
  157.     }
  158.        if (numProcessors == 1) {
  159.        fprintf(stream," Elapsed time ");
  160.         PrintTimes(stream, (Proc_ResUsage *)0, timePtr);
  161.     } else {
  162.         fprintf(stream, "\n");
  163.     }
  164.     }
  165.     if (numProcessors != 1) {
  166.     fprintf(stream,
  167.     "Total: Idle ticks %0.0f/%d = %6.2f%% Idle, Context Sw. %d inv %d full %d, Elapsed time ",
  168.     totalLowTicks, totalIdleTicksPerSecond, 
  169.     totalLowTicks / (double) totalIdleTicksPerSecond * 100.0,
  170.     totalCS, totalInvCS, totalFullCS);
  171.     PrintTimes(stream, (Proc_ResUsage *)0, timePtr);
  172.     }
  173. }
  174.  
  175.  
  176. /*
  177.  *----------------------------------------------------------------------
  178.  *
  179.  * PrintFs_Stats --
  180.  *
  181.  *    Print out the filesystem statistics.  If both a start and end
  182.  *    sample of the statistics are given then the differences between
  183.  *    the two are printed.  To just print the total cumulative statistics
  184.  *    from one sample, specify a single Fs_Stats buffer with the 'end'
  185.  *    parameter.
  186.  *
  187.  * Results:
  188.  *    None.
  189.  *
  190.  * Side effects:
  191.  *    Prints to the specified stream
  192.  *
  193.  *----------------------------------------------------------------------
  194.  */
  195. void
  196. PrintFs_Stats(stream, start, end, verbose)
  197.     FILE *stream;    /* Output stream */
  198.     Fs_Stats *start;    /* 0, or address of "before run" statistics */
  199.     Fs_Stats *end;    /* End of run statistics */
  200.     int verbose;    /* If true, everything is dumped */
  201. {
  202.     register int t1, t2, t3, t4, t5;
  203.     Fs_Stats zeroStats;
  204.  
  205.     if (start == (Fs_Stats *)0) {
  206.     bzero(&zeroStats, sizeof(Fs_Stats));
  207.     start = &zeroStats;
  208.     }
  209.     /*
  210.      * Print cache size
  211.      */
  212.     fprintf(stream, "Cache blocks max %d min %d number %d/%d free %d/%d limit %d\n",
  213.                end->blockCache.maxCacheBlocks,
  214.                end->blockCache.minCacheBlocks,
  215.                start->blockCache.numCacheBlocks,
  216.                end->blockCache.numCacheBlocks,
  217.                start->blockCache.numFreeBlocks,
  218.                end->blockCache.numFreeBlocks,
  219.                end->blockCache.maxNumBlocks);
  220.  
  221.     /*
  222.      * Print bytes read traffic ratio
  223.      */
  224.     t1 = end->blockCache.bytesRead - start->blockCache.bytesRead;
  225.     t2 = end->blockCache.dirBytesRead - start->blockCache.dirBytesRead;
  226.     t3 = end->gen.remoteBytesRead - start->gen.remoteBytesRead;
  227.     t4 = end->gen.fileBytesRead - start->gen.fileBytesRead;
  228.     t5 = end->gen.physBytesRead - start->gen.physBytesRead;
  229.     fprintf(stream, "Bytes read %d+%d remote %d disk %d+%d",
  230.                t1, t2, t3, t4, t5);
  231.     if (t1 + t2 > 0) {
  232.     fprintf(stream, "\ttraffic ratio %%%d\n",
  233.                (int)((double)(t3+t4+t5)/(double)(t1+t2) * 100.));
  234.     } else {
  235.     fprintf(stream, "\n");
  236.     }
  237.  
  238.     /*
  239.      * Print bytes written traffic ratio
  240.      */
  241.     t1 = end->blockCache.bytesWritten - start->blockCache.bytesWritten +
  242.     (end->blockCache.fileDescWrites - start->blockCache.fileDescWrites +
  243.      end->blockCache.indBlockWrites - start->blockCache.indBlockWrites) *
  244.     FS_BLOCK_SIZE;
  245.     t2 = end->blockCache.dirBytesWritten - start->blockCache.dirBytesWritten;
  246.     t3 = end->gen.remoteBytesWritten - start->gen.remoteBytesWritten;
  247.     t4 = end->gen.fileBytesWritten - start->gen.fileBytesWritten;
  248.     t5 = end->gen.physBytesWritten - start->gen.physBytesWritten;
  249.     fprintf(stream, "Bytes written %d+%d remote %d disk %d+%d",
  250.                t1, t2, t3, t4, t5);
  251.     if (t1 + t2 > 0) {
  252.     fprintf(stream, "\ttraffic ratio %%%d",
  253.                (int)((double)(t3+t4+t5)/(double)(t1+t2) * 100.));
  254.     }
  255.     fprintf(stream, "\n");
  256.  
  257.     if (verbose) {
  258.     /*
  259.      * Print device bytes and zero fills
  260.      */
  261.     t1 = end->gen.deviceBytesWritten - start->gen.deviceBytesWritten;
  262.     t2 = end->gen.deviceBytesRead - start->gen.deviceBytesRead;
  263.     fprintf(stream, "Dev bytes read %d written %d\n", t1, t2);
  264.     t1 = end->blockCache.readZeroFills - start->blockCache.readZeroFills;
  265.     t2 = end->blockCache.writeZeroFills1 -
  266.         start->blockCache.writeZeroFills1;
  267.     t3 = end->blockCache.writeZeroFills2 -
  268.         start->blockCache.writeZeroFills2;
  269.     t4 = end->blockCache.fragZeroFills - start->blockCache.fragZeroFills;
  270.     fprintf(stream, "Zero Fills read %d write1 %d write2 %d frag %d\n",
  271.                    t1, t2, t3, t4);
  272.     t1 = end->blockCache.appendWrites - start->blockCache.appendWrites;
  273.     t2 = end->blockCache.overWrites - start->blockCache.overWrites;
  274.     t3 = end->blockCache.domainReadFails -
  275.         start->blockCache.domainReadFails;
  276.     fprintf(stream, "Appends %d Overwrites %d Failed Reads %d\n",
  277.                    t1, t2, t3);
  278.     }
  279.     t1 = end->blockCache.readAccesses - start->blockCache.readAccesses +
  280.      end->blockCache.fragAccesses - start->blockCache.fragAccesses +
  281.      end->blockCache.fileDescReads - start->blockCache.fileDescReads +
  282.      end->blockCache.indBlockAccesses - start->blockCache.indBlockAccesses +
  283.      end->blockCache.dirBlockAccesses - start->blockCache.dirBlockAccesses;
  284.     t2 = end->blockCache.readHitsOnDirtyBlock -
  285.     start->blockCache.readHitsOnDirtyBlock;
  286.     t3 = end->blockCache.readHitsOnCleanBlock -
  287.     start->blockCache.readHitsOnCleanBlock;
  288.     t4 = end->blockCache.fragHits - start->blockCache.fragHits +
  289.      end->blockCache.fileDescReadHits - start->blockCache.fileDescReadHits +
  290.      end->blockCache.indBlockHits - start->blockCache.indBlockHits +
  291.      end->blockCache.dirBlockHits - start->blockCache.dirBlockHits;
  292.     fprintf(stream, "Cache reads %d hits: dirty %d clean %d other %d",
  293.                t1, t2, t3, t4);
  294.     if (t1 != 0) {
  295.     fprintf(stream, "\thit ratio %%%d",
  296.                (int)((double)(t2+t3+t4)/(double)t1 * 100.));
  297.     }
  298.     fprintf(stream, "\n");
  299.  
  300.     t1 = end->blockCache.readAheads - start->blockCache.readAheads;
  301.     t2 = end->blockCache.readAheadHits - start->blockCache.readAheadHits;
  302.     t3 = end->blockCache.allInCacheCalls - start->blockCache.allInCacheCalls;
  303.     t4 = end->blockCache.allInCacheTrue - start->blockCache.allInCacheTrue;
  304.     if (t1 > 0) {
  305.     fprintf(stream, "Read Ahead: hits %d/%d all-in-cache %d/%d\n",
  306.             t2, t1, t4, t3);
  307.     }
  308.  
  309.     t1 = end->blockCache.writeAccesses - start->blockCache.writeAccesses +
  310.      end->blockCache.fileDescWrites - start->blockCache.fileDescWrites +
  311.      end->blockCache.indBlockWrites - start->blockCache.indBlockWrites +
  312.      end->blockCache.dirBlockWrites - start->blockCache.dirBlockWrites;
  313.     t2 = end->blockCache.partialWriteHits - start->blockCache.partialWriteHits +
  314.     end->blockCache.fileDescWriteHits - start->blockCache.fileDescWriteHits;
  315.     t3 = end->blockCache.partialWriteMisses -
  316.     start->blockCache.partialWriteMisses;
  317.     t4 = end->blockCache.blocksWrittenThru -
  318.     start->blockCache.blocksWrittenThru;
  319.     fprintf(stream, "Cache writes %d hits %d misses %d thru %d",
  320.                t1, t2, t3, t4);
  321.     if (t1 != 0) {
  322.     fprintf(stream, "\ttraffic ratio %%%d",
  323.                (int)((double)(t3+t4)/(double)t1 * 100.));
  324.     }
  325.     fprintf(stream, "\n");
  326.     
  327.     fprintf(stream, "Write thru %d data %d indirect %d desc %d dir %d\n",
  328.                t4,
  329.                end->blockCache.dataBlocksWrittenThru -
  330.                start->blockCache.dataBlocksWrittenThru,
  331.                end->blockCache.indBlocksWrittenThru -
  332.                start->blockCache.indBlocksWrittenThru,
  333.                end->blockCache.descBlocksWrittenThru -
  334.                start->blockCache.descBlocksWrittenThru,
  335.                end->blockCache.dirBlocksWrittenThru -
  336.                start->blockCache.dirBlocksWrittenThru);
  337.     if (end->blockCache.fileDescReads > 0) {
  338.     fprintf(stream, "File descriptor reads %d hits %d writes %d hits %d\n",
  339.                    end->blockCache.fileDescReads -
  340.                    start->blockCache.fileDescReads,
  341.                    end->blockCache.fileDescReadHits -
  342.                    start->blockCache.fileDescReadHits,
  343.                    end->blockCache.fileDescWrites -
  344.                    start->blockCache.fileDescWrites,
  345.                    end->blockCache.fileDescWriteHits -
  346.                    start->blockCache.fileDescWriteHits);
  347.     }
  348.     if (end->blockCache.indBlockAccesses > 0) {
  349.     fprintf(stream, "Indirect block reads %d hits %d writes %d\n",
  350.                end->blockCache.indBlockAccesses -
  351.                start->blockCache.indBlockAccesses,
  352.                end->blockCache.indBlockHits -
  353.                start->blockCache.indBlockHits,
  354.                end->blockCache.indBlockWrites -
  355.                start->blockCache.indBlockWrites);
  356.     }
  357.     if (end->blockCache.dirBlockAccesses > 0) {
  358.     fprintf(stream, "Directory block reads %d hits %d writes %d\n",
  359.                    end->blockCache.dirBlockAccesses -
  360.                    start->blockCache.dirBlockAccesses,
  361.                    end->blockCache.dirBlockHits -
  362.                    start->blockCache.dirBlockHits,
  363.                    end->blockCache.dirBlockWrites -
  364.                    start->blockCache.dirBlockWrites);
  365.     }
  366.     if (end->blockCache.vmRequests > 0) {
  367.     fprintf(stream, "VM requests %d tried %d gave %d\n",
  368.                    end->blockCache.vmRequests -
  369.                    start->blockCache.vmRequests,
  370.                    end->blockCache.triedToGiveToVM -
  371.                    start->blockCache.triedToGiveToVM,
  372.                    end->blockCache.vmGotPage -
  373.                    start->blockCache.vmGotPage);
  374.     }
  375.     fprintf(stream, "Cache blocks created %d, alloc from free %d part %d lru %d\n",
  376.                    end->blockCache.unmapped -
  377.                    start->blockCache.unmapped,
  378.                    end->blockCache.totFree -
  379.                    start->blockCache.totFree,
  380.                    end->blockCache.partFree -
  381.                    start->blockCache.partFree,
  382.                    end->blockCache.lru -
  383.                    start->blockCache.lru);
  384.     if (end->alloc.blocksAllocated > 0) {
  385.     fprintf(stream, "Disk blocks alloc %d free %d search %d/%d hash %d\n",
  386.                    end->alloc.blocksAllocated -
  387.                    start->alloc.blocksAllocated,
  388.                    end->alloc.blocksFreed -
  389.                    start->alloc.blocksFreed,
  390.                    end->alloc.cylsSearched -
  391.                    start->alloc.cylsSearched,
  392.                    end->alloc.cylBitmapSearches -
  393.                    start->alloc.cylBitmapSearches,
  394.                    end->alloc.cylHashes -
  395.                    start->alloc.cylHashes);
  396.     fprintf(stream, "Fragments alloc %d free %d upgrade %d blocks made %d used %d, bad hints %d\n",
  397.                    end->alloc.fragsAllocated -
  398.                    start->alloc.fragsAllocated,
  399.                    end->alloc.fragsFreed -
  400.                    start->alloc.fragsFreed,
  401.                    end->alloc.fragUpgrades -
  402.                    start->alloc.fragUpgrades,
  403.                    end->alloc.fragToBlock -
  404.                    start->alloc.fragToBlock,
  405.                    end->alloc.fullBlockFrags -
  406.                    start->alloc.fullBlockFrags,
  407.                    end->alloc.badFragList -
  408.                    start->alloc.badFragList);
  409.     }
  410.     if (end->nameCache.accesses > 0) {
  411.     fprintf(stream, "Name cache entries %d accesses %d hits %d replaced %d\n",
  412.                end->nameCache.size,
  413.                end->nameCache.accesses -
  414.                start->nameCache.accesses,
  415.                end->nameCache.hits -
  416.                start->nameCache.hits,
  417.                end->nameCache.replacements -
  418.                start->nameCache.replacements);
  419.     }
  420.     fprintf(stream, "Handles %d created %d installed %d hits %d old %d version %d flush %d\n",
  421.                end->handle.exists,
  422.                end->handle.created -
  423.                start->handle.created,
  424.                end->handle.installCalls -
  425.                start->handle.installCalls,
  426.                end->handle.installHits -
  427.                start->handle.installHits,
  428.                0,
  429.                end->handle.versionMismatch -
  430.                start->handle.versionMismatch,
  431.                end->handle.cacheFlushes -
  432.                start->handle.cacheFlushes);
  433.     fprintf(stream, "\tfetched %d hits %d released %d locks %d/%d wait %d\n",
  434.                end->handle.fetchCalls -
  435.                start->handle.fetchCalls,
  436.                end->handle.fetchHits -
  437.                start->handle.fetchHits,
  438.                end->handle.release -
  439.                start->handle.release,
  440.                end->handle.locks -
  441.                start->handle.locks,
  442.                end->handle.locks -
  443.                start->handle.locks,
  444.                end->handle.lockWaits -
  445.                start->handle.lockWaits);
  446.     fprintf(stream, "Segments fetched %d hits %d\n",
  447.                end->handle.segmentFetches -
  448.                start->handle.segmentFetches,
  449.                end->handle.segmentHits -
  450.                start->handle.segmentHits);
  451.     fprintf(stream, "Lookup relative %d absolute %d redirect %d found %d loops %d timeouts %d stale %d\n",
  452.                end->prefix.relative -
  453.                start->prefix.relative,
  454.                end->prefix.absolute -
  455.                start->prefix.absolute,
  456.                end->prefix.redirects -
  457.                start->prefix.redirects,
  458.                end->prefix.found -
  459.                start->prefix.found,
  460.                end->prefix.loops -
  461.                start->prefix.loops,
  462.                end->prefix.timeouts -
  463.                start->prefix.timeouts,
  464.                end->prefix.stale -
  465.                start->prefix.stale);
  466. }
  467.  
  468.  
  469. /*
  470.  *----------------------------------------------------------------------
  471.  *
  472.  * PrintDiskStats --
  473.  *
  474.  *    Print out statistics for the disks.  If both a start and end
  475.  *    sample of the statistics are given then the differences between
  476.  *    the two are printed.  To just print the total cumulative statistics
  477.  *    from one sample, specify a single VmStats buffer with the 'end'
  478.  *    parameter.
  479.  *
  480.  * Results:
  481.  *    None.
  482.  *
  483.  * Side effects:
  484.  *    Prints to the specified stream
  485.  *
  486.  *----------------------------------------------------------------------
  487.  */
  488. void
  489. PrintDiskStats(stream, start, end)
  490.     FILE         *stream;/* Output stream */
  491.     Sys_DiskStats    *start;    /* 0, or address of "before run" statistics */
  492.     Sys_DiskStats    *end;    /* End of run statistics */
  493. {
  494.     int    i = 0;
  495.     while (1) {
  496.     if (end[i].name[0] == 0) {
  497.         return;
  498.     }
  499.     if (start == 0) {
  500.         fprintf(stream, "Disk (%s, %d): %0.2f%% Idle Reads %d Writes %d\n",
  501.             end[i].name, end[i].controllerID,
  502.             100 * ((float)end[i].idleCount / (float)end[i].numSamples),
  503.             end[i].diskReads, end[i].diskWrites);
  504.     } else {
  505.         fprintf(stream, "Disk (%s, %d) %0.0f%% Idle Reads %d Writes %d\n",
  506.             end[i].name, end[i].controllerID,
  507.             100 * ((float)(end[i].idleCount - start[i].idleCount) /
  508.                    (float)(end[i].numSamples - start[i].numSamples)),
  509.             end[i].diskReads - start[i].diskReads,
  510.             end[i].diskWrites - start[i].diskWrites);
  511.     }
  512.     i++;
  513.     }
  514. }
  515.  
  516.  
  517.